package com.clinbrain;

import com.facebook.presto.spi.function.Description;
import com.facebook.presto.spi.function.ScalarFunction;
import com.facebook.presto.spi.function.SqlType;
import com.facebook.presto.spi.type.StandardTypes;
import io.airlift.slice.Slice;
import io.airlift.slice.Slices;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public final class JudgeColumnType {

    private static Pattern NUMBER_PATTERN = Pattern.compile("^([1-9]+[.]?[0-9]*|[.][0-9]+)$");

    private JudgeColumnType() {

    }

    @ScalarFunction("isnumberdate")
    @Description("judge column value type.")
    @SqlType(StandardTypes.VARCHAR)
    public static Slice isNumberOrDate(@SqlType(StandardTypes.VARCHAR) Slice column) {
        if (null == column) {
            return null;
        }

        String columnValue = column.toStringUtf8();
        if (columnValue.equals("0")) {
            return Slices.utf8Slice("knumber");
        }

        Matcher matcher = NUMBER_PATTERN.matcher(columnValue);
        if (matcher.find()) {
            if (columnValue.length() < 53) {
                return Slices.utf8Slice("knumber");
            }
        }

        DateTimeFormatter dateTimeFormatter = null;
        switch (columnValue.length()) {
            case 23:
                dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
                break;
            case 19:
                dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                break;
            case 16:
                dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
                break;
            case 13:
                dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH");
                break;
            case 10:
                dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
                break;
        }

        if (null != dateTimeFormatter) {
            try {
                if (10 != columnValue.length()) {
                    LocalDateTime.parse(columnValue, dateTimeFormatter);
                } else {
                    LocalDate.parse(columnValue, dateTimeFormatter);
                }

                return Slices.utf8Slice("kdate");
            } catch (DateTimeParseException e) {
                //do nothing
            }
        }

        return Slices.utf8Slice("kvarchar");
    }

    public static void main(String[] args) {
        String str1 = "111111111111111111111111111111111111111111111111111111111111111111111111111111111111111";
        Slice slice = isNumberOrDate(Slices.utf8Slice(str1));
        System.out.println(slice.toStringUtf8());

        String str2 = "11111.11";
        slice = isNumberOrDate(Slices.utf8Slice(str2));
        System.out.println(slice.toStringUtf8());

        String str3 = "0";
        slice = isNumberOrDate(Slices.utf8Slice(str3));
        System.out.println(slice.toStringUtf8());

        String str4 = "2001-01-02 10:12:12.123";
        slice = isNumberOrDate(Slices.utf8Slice(str4));
        System.out.println(slice.toStringUtf8());

        String str5 = "2001-19-02 10:12:12";
        slice = isNumberOrDate(Slices.utf8Slice(str5));
        System.out.println(slice.toStringUtf8());

        String str6 = "2001-01-02 10:12:12";
        slice = isNumberOrDate(Slices.utf8Slice(str6));
        System.out.println(slice.toStringUtf8());

        String str7 = "2001-01-02 10:12";
        slice = isNumberOrDate(Slices.utf8Slice(str7));
        System.out.println(slice.toStringUtf8());

        String str8 = "2001-01-02 10";
        slice = isNumberOrDate(Slices.utf8Slice(str8));
        System.out.println(slice.toStringUtf8());

        String str9 = "2001-01-02";
        slice = isNumberOrDate(Slices.utf8Slice(str9));
        System.out.println(slice.toStringUtf8());
    }
}
